Server Action

  • Step 1:

    1. Create server action and call that action from your menu.

    
                   <record id="server_action_any_name" model="ir.actions.server">
                  <field name="name">Any Name Goes Here</field>
                  <field name="condition">True</field>
                  <field name="type">ir.actions.server</field>
                  <field name="model_id" ref="model_your_model_name" />
                  <field name="state">code</field>
                  <field name="code">action=self.get_filtered_record(cr, uid, context.get('active_ids', []), context=context)</field>
                </record>
    
                <menuitem name="Your Menu Name" id="menu_any_name" action="server_action_any_name"/>
    
                

    2. After that create a method or function under your model, and from that model after using your logic return action window.

    
                def get_filtered_record(self):
    
                
  • Details:

    Action Type: Where we define the type or category of the current action.

    res_model,
                       binding_model_id,
                        binding_view_types,
                         view_id,
                          view_ids,
                           view_mode,
                            view_type,
                             search_view_id,
                              state, 
                              code,
                               domain,
                                context,
                                 target etc.

    The available server actions are :

    
                    * code: Executes python code given in the argument  of code.
    
                    * object_create: It creates a new record.
    
                    * object_write: Update the current record.
    
                    * multi: Executes several actions given in the argument of child_ids.
    
                    

    Code example

    
    
                    <record id="action_server" model="ir.actions.server">
                    <field name="name">Test Server Action</field>
                    <field name="model_id" ref="model_test_model"/>
                    <field name="binding_model_id" ref="model_test_model"/>
                    <field name="binding_view_types">list</field>
                    <field name="state">code</field>
                    <field name="code">
                          action = model.action_test_code()
                    </field>
                </record>
    
    

    This will execute the method action_test_code() in the model test model.

  • Example:

    Button

    
                      <button name="action_confirm" string="Confirm" class="btn-primary" type="object" />
    

    create a sales target model like below.

    
    
                     from odoo import models, fields, api, exceptions, _
     
    class SalesTarget(models.Model):
        _name = 'ng.sale.target'
     
        name = fields.Char(default='Sales Target')
        target_line_id = fields.One2many('ng.sale.target.line', 'target_id')
         
     
    class SalesTargetLine(models.Model):
        _name = 'ng.sale.target.line'
     
        user_id = fields.Many2one('res.users', string='Sales Person')
        total_target = fields.Float(string='Total Target', default=0)
        target_id = fields.Many2one('ng.sale.target')
    
    
    

    Then make the form.

    
    <record id="ng_sale_target_form" model="ir.ui.view">
        <field name="name">Sales Target</field>
        <field name="model">ng.sale.target</field>
        <field name="arch" type="xml">
            <form string="Sales Target" create="0" delete="0">
                <sheet>
                    <h2>Enter the sales target per Sales Person</h2>
                    <notebook>
                        <page string="Sales Target">
                            <field name="target_line_id">
                                <tree editable="bottom">
                                    <field name="user_id" />
                                    <field name="total_target" />
                                </tree>
                            </field>
                        </page>
                    </notebook>
                </sheet>
            </form>
        </field>
    </record>
    
    

    Next, create a menu item and an action server.

    
    
    <record id="action_open_sale_target_form" model="ir.actions.server">
        <field name="name">Sales Target</field>
        <field name="type">ir.actions.server</field>
        <field name="state">code</field>
        <!-- model name -->
        <field name="model_id" ref="model_ng_sale_target"/> 
        <!-- The name of the method to be called -->
        <field name="code">action = model.open_sales_target()</field>
    </record>
     
    <!-- Menuitem on Sales >> Configuration menu -->
    <menuitem name="Sales Target"
            id="menu_sale_target"
            parent="sale.menu_sale_config"
            action="action_open_sale_target_form" />
    
    

    Finally add a method with the same name with the Action Server above to the model.

    
    def open_sales_target(self):
        # check whether there is a sales target data or not
        existed_data = self.env['ng.sale.target'].search([],limit=1)
     
        # if no, create the new one
        if not existed_data:
            existed_data = self.create({})        
         
        # display the sales target data to the user using an Action Window
        return {
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'ng.sale.target',
            'res_id': existed_data.id,
        }